
package models;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.*;

import models.Organization;
import models.Role;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;

import controllers.Comments;

import play.data.validation.Required;
import play.db.jpa.JPABase;
import play.db.jpa.Model;

@Entity
public class User extends Model 
{
	@Required
	private String	fName; 						// First name of user, Tarek Sheasha
	@Required
	private String	lName;						// Last name of user, Tarek Sheasha
	@Required
	@Column( unique = true )
	private String	username; 					// Username of user, Tarek Sheasha
	@Required
	private String	password; 					// Password of user, Tarek Sheasha
	@Required
	private String	phoneNumber;				// Phone Number of user, Tarek Sheasha
	@Required
	private String	address;					// Address of user, Tarek Sheasha
	@Required
	@Column( unique = true )
	private String	email;						// Email of user, Tarek Sheasha
	
	// Property of Admin if true then this User is an Admin not a Normal Idea Developer, 
	// Once it is true a new Admin() will be created with the 
	// corresponding data passed into the constructor
	// Done since this will be the one saved in the database once not the Admin Model
	// Tarek Sheasha
	
	@Required
	private boolean 			isAdmin; 			// is this user an admin? T: F
	private boolean 			isDeleted;          //is this user deleted or still on the system
	private int 				pointCounter;		// Point Counter of user, Tarek Sheasha
	@ManyToMany (mappedBy = "users",  cascade=CascadeType.ALL)
	private List<Item>          items;
	@ManyToMany (mappedBy = "users", cascade=CascadeType.ALL)
	private List<Plan> 			plans;
	@Required
	@OneToMany (mappedBy = "user", cascade=CascadeType.ALL) 
	public List<Role>			roleList;			// Role of user (Organiser, Lead, None), Tarek Sheasha
	@ManyToMany (cascade=CascadeType.ALL)
	private List<Idea>			ideaList; 			// List of user Ideas, Tarek Sheasha
	@ManyToMany (cascade=CascadeType.ALL)
	private List<Topic>			topicList;			// List of user Topics, Tarek Sheasha
	@OneToMany (mappedBy = "sender", cascade=CascadeType.ALL)
	private List<Notification> 	sentNotifications; 	// List of user Notifications that have been sent, Tarek Sheasha
	@OneToMany (mappedBy = "receiver", cascade=CascadeType.ALL)
	private List<Notification> 	receivedNotifications; 	// List of user Notifications that have been received, Tarek Sheasha
	@ManyToMany (mappedBy = "members", cascade=CascadeType.ALL)
	private List<Eentity> 		entityList; 		// Last of user Entities, Tarek Sheasha
	@ManyToMany (mappedBy = "users", cascade=CascadeType.ALL)
	private List<Tag> 			tagList; 			// List of user Tags, Tarek Sheasha	
	@OneToMany (mappedBy = "sender", cascade=CascadeType.ALL)
	private List<Comment> 		commentList;		// List of user Comments, Tarek Sheasha
    @OneToOne (mappedBy = "sender", cascade=CascadeType.ALL)
	private Request             sentRequest;        // Requests sent by User
    @OneToOne (mappedBy = "reciever", cascade=CascadeType.ALL)
    private Request             receivedRequest;    //Requests Received By User
    @OneToMany (mappedBy = "sender", cascade=CascadeType.ALL)
    private List<Invitation> 	sentInvitations; 	// List of user Invitations that have been sent, Tarek Sheasha
    @OneToMany (mappedBy = "receiver", cascade=CascadeType.ALL)
    private List<Invitation> 	receivedInvitations;// List of user Invitations that have been received, Tarek Sheasha 	
	@ManyToMany (mappedBy = "members", cascade=CascadeType.ALL)
    private List<Organization>  organizationList;   // List of All organisations a user belongs to, Tarek Sheasha
	
	private LinkedList<String>	tempPrivilegeList; 	// Temporary List of unregistered user Privileges .Nirmeen Sallam
	
	private LinkedList<String>	privilegeList; 	// Temporary List of unregistered user Privileges .Nirmeen Sallam
	/**
	 *	User Empty Constructor
	 * 
	 * @author		Rania Nader Saeed
	 * @version 	2011.04.25
	 * @category 	C1S1
	 * @param		nothing    
	 * @return 		nothing
	 */
	public User()//Default Constructor for User, Rania Saeed
	{
		fName			= ""	;
		lName			= ""	;
		username		= ""	;
		password		= ""	;
		phoneNumber		= ""    ;		
		address			= ""	;
		email			= ""	;
		isAdmin			= false	;
		pointCounter	= 0		;
		isDeleted       = false ;
		roleList		      = new LinkedList<Role>			();
		ideaList		      = new LinkedList<Idea>			();
		topicList		      = new LinkedList<Topic>			();
		sentNotifications     = new LinkedList<Notification>	();
		receivedNotifications = new LinkedList<Notification>	();
		entityList		      = new LinkedList<Eentity>	();
		tagList			      = new LinkedList<Tag>			    ();
		commentList		      = new LinkedList<Comment>		    ();
		sentInvitations       = new LinkedList<Invitation>	    ();
		receivedInvitations   = new LinkedList<Invitation>	    ();
	    tempPrivilegeList     = new LinkedList<String>		    ();
	    privilegeList         = new LinkedList<String>		    ();
	    organizationList      = new LinkedList<Organization>    ();
	    plans                 = new LinkedList<Plan> ();
	    items                 = new LinkedList<Item>();
	}
	
	public User(LinkedList<String> attributes)
	{
		this(); // Called Empty Constructor here as to avoid redundant lines of code, Tarek Sheasha
		this.fName			= attributes.get(0);
		this.lName 			= attributes.get(1);
		this.username 		= attributes.get(2);
		this.password 		= attributes.get(3);
		this.phoneNumber 	= attributes.get(4);
		this.address 		= attributes.get(5);
		this.email 			= attributes.get(6);
	}

	public User(String fName,String lName , String email)//Information entered by a User about Unregistered User to be Invited ,Nirmeen Sallam 
	{
		this();
		this.fName			= fName;
		this.lName 			= lName;
		this.email 			= email;
	}
	
	/**
	 *	A method that creates a user and saves him to the database
	 *	method was created for test purposes 
	 * 
	 * @author		Amr Draz
	 * @version 	2011.05.03
	 * @category 	C4S14
	 * @param		username: the username of the user
	 * 				password: the password of te user
	 *				email: the email of te user
	 * @return 		User: the user that was just created
	 */
	public static User newUser(String username, String password, String email) {
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		user.setEmail(email);
		// user.save();
		return user;
	}
	
	/**
	 * edits this user's info
	 *
	 * @author		Doaa El-Hawary
	 * @version		2011.0424
	 * @category	C1S2
	 * @param		Attributes: the attributes that should be edited
	 * @return		void because it just edits the info in the system.
	 */
	public void editInfo(String fname,
					String lname,
					String username,
					String password,
					String phoneNumber,
					String address,
					String email,
					boolean isAdmin) {
		fName 		= fname;
		lName 		= lname;
		this.username 	= username;
		this.password 	= password;
		this.phoneNumber = phoneNumber;
		this.address 	= address;
		this.email 		= email;
		this.isAdmin = isAdmin;
		}
	
	/**
	 * gets this user's type/role in a certain organization
	 *
	 * @author		Doaa El-Hawary
	 * @version		2011.0505
	 * @category	C1D3
	 * @param		--
	 * @return		String: Role/type of a user in a certain organization
	 */
	public String getUserType(Organization organization) {
		for(int i=0; i<roleList.size(); i++) {
			if(roleList.get(i).getRelatedOrganization() != null) {
				String orgName = organization.getName();
				Role currentRole = roleList.get(i);
				if(currentRole.getRelatedOrganization() != null) {
					Organization thisOrg = currentRole.getRelatedOrganization();
					String relatedOrg = thisOrg.getName();
					if(orgName.equals(relatedOrg)) {
						return roleList.get(i).getTitle();
					}
				}
			}
		}
		return "Error! Organization not found!";
	}
	
	/**
	 * gets this user's list of ideas
	 *
	 * @author		Doaa El-Hawary
	 * @version		2011.0424
	 * @category	C1D2
	 * @param		--
	 * @return		LinkedList<Idea>
	 */
	public LinkedList<Idea> getUserIdeas() {
		return (LinkedList<Idea>) ideaList;
	}
	
	/**
	 * returns the list of all the users on the system
	 *
	 * @author      Rania Nader Saeed
	 * @version     2011.04.25
	 * @category   	C1D1
	 * @params    	no input
	 * @return      returns a linkedlist of users
	 */
	public List<User> findAllUsers() {
		return User.findAll();
	}
	
	/**
	 * sends a notification for a specific action.
	 * Also, this method sends an email to the receiver of 
	 * this notification.
	 *
	 * @author      Rania Nader Saeed
	 * @version     2011.04.25
	 * @category   	C1D6
	 * @param    	receiver of the notification
	 * 				subject of the notification
	 * 				content of the notification
	 * @return      returns a boolean indicating true if 
	 * 				the notification was sent, and false otherwise.
	 * @throws		EmailException 
	 */
	public boolean sendNotification(User receiver, String subject, String content) throws EmailException
	{
		Notification notification	= new Notification();
		Date now					= new Date();
		SimpleEmail email			= new SimpleEmail();
		
		notification.setSender(this);
		notification.setReceiver(receiver);
		notification.setSubject(subject);
		notification.setContent(content);
		notification.setDate(now);
		
		receiver.receivedNotifications.add(notification);
		this.sentNotifications.add(notification);
				
		email.setHostName("smtp.gmail.com");
		email.setSmtpPort(587);
		email.setAuthenticator(new DefaultAuthenticator(notification.getSender().getUsername(), notification.getSender().getPassword()));
		email.setTLS(true);
		email.setFrom(notification.getSender().getEmail());
		email.setSubject(notification.getSubject());
		email.setMsg(content);
		email.addTo(notification.getReceiver().getEmail());
		email.send();
		return true;
	}
	
	/**
	 * increments user's pointCounter when he posts idea
	 * 
	 * @author Caroline Tawfik
	 * @version 2011.0426
	 * @category C3S11
	 * @params user: the user who posted the idea to increment his pointCounter
	 * @return void
	 */
	public static void incrementIdeaCounter(User user) {

		user.setPointCounter(user.getPointCounter() + 1);
		user.save();
	}

	/**
	 * increments user's pointCounter when idea is executed
	 * 
	 * @author Caroline Tawfik
	 * @version 2011.0426
	 * @category C3S12
	 * @params user: the user whose idea was executed to increment his
	 *         pointCounter
	 * @return void
	 */
	public static void incrementExecutionCounter(User user) {

		user.setPointCounter(user.getPointCounter() + 10);
		user.save();
	}
	
	
	/**
	 * Invites a User to join something
	 * @author Tarek Sheasha
	 * @category C1S8
	 * @Version 26.02.2011
	 * @param toBeInvited, content, date, organization, entity, newRole
	 * @return nothing
	 * 
	 */
	public void inviteUser(User toBeInvited, String content, String date, Organization organization, Eentity entity, Role newRole) {
			Invitation toUser = new Invitation(this, toBeInvited,content);
			
			if (organization != null)
			toUser.setAssignedOrganization(organization);
			else
			toUser.setAssignedEntity(entity);
			toUser.setAssignedRole(newRole);
			toBeInvited.getRoleList().add(newRole);
			newRole.setUsers(toBeInvited);
			toBeInvited.receivedInvitations.add(toUser);
			this.sentInvitations.add(toUser);
			toUser.setReceiver(toBeInvited);
			toUser.setSender(this);
			try {
				this.sendNotification(toBeInvited, "Invitation", content);
			} catch (EmailException e) {
				e.printStackTrace();
			}
			toUser.save();
			this.save();
			toBeInvited.save();
	}
	
	
	/**
	 * accept method to accept entry into an organization
	 * @author Tarek Sheasha
	 * @category C1S8
	 * @version 27.04.2011
	 * @param invitation : invitation sent to user
	 *
	 */
	public void acceptInvitationOrganization(Invitation invitation)  {
			
		this.getOrganizationList().add(invitation.getAssignedOrganization());
		
		this.getRoleList().add(invitation.getAssignedRole());
		invitation.getAssignedOrganization().getMembers().add(invitation.getReceiver());
		try {
			invitation.getReceiver().sendNotification(
				    invitation.getSender(),"Invitation Accepted!", "Invitation to Join Organization " +
				    invitation.getAssignedOrganization().getName() +" by "+ "/n" +
				    invitation.getReceiver().getfName() + " " +
				    invitation.getReceiver().getlName() + " has been accepted!");
		} catch (EmailException e) {
		
			e.printStackTrace();
		}
				
		invitation.setStatus("Accepted");
				
		this.save();
		invitation.getAssignedOrganization().save();
		invitation.getSender().save();
	}
	
	/**
	 * reject method to reject invitation to enter an organization
	 * @author Tarek Sheasha
	 * @category C1S8
	 * @version 27.04.2011
	 * @param invitation : invitation sent to user
	 * 
	 */
	public void rejectInvitationOrganization(Invitation invitation) {
			
		try {
			invitation.getReceiver().sendNotification(
				    invitation.getSender(),"Invitation Rejected!", "Invitation to Join Organization " +
				    invitation.getAssignedOrganization().getName() +" by "+ "/n" +
				    invitation.getReceiver().getfName() + " " +
				    invitation.getReceiver().getlName() + " has been rejected!");
		} catch (EmailException e) {
		
			e.printStackTrace();
		}
				
		invitation.setStatus("Rejected");		
		this.save();
		invitation.getSender().save();
	}
	
	/**
	 * accept method to accept entry of Unregistered User into an Entity
	 * @author Tarek Sheasha
	 * @category C1S5
	 * @version 27.04.2011
	 * @param invitation : invitation sent to user
	 * 
	 * @returns nothing 
	 */
	public void acceptUnregInvitationEntity(Invitation invitation)  {
			
		this.getEntityList().add(invitation.getAssignedEntity());
		
		this.getRoleList().add(invitation.getAssignedRole());
		invitation.getAssignedEntity().getMembers().add(invitation.getReceiver());
		try {
			invitation.getReceiver().sendNotification(
				    invitation.getSender(),"Invitation Accepted!", "Invitation to Join Entity " +
				    invitation.getAssignedEntity().getName() +" by "+ "/n" +
				    invitation.getReceiver().getfName() + " " +
				    invitation.getReceiver().getlName() + " has been accepted!");
		} catch (EmailException e) {
		
			e.printStackTrace();
		}
				
		invitation.setStatus("Accepted");
		invitation.getAssignedEntity().save();		
		this.save();
		invitation.getSender().save();
	}	
	
	/**
	 * Rejects invitation of unregistered user to an entity
	 * @author Tarek Sheasha
	 * @category C1S5
	 * @version 27.04.2011
	 * @param invitation  : invitation sent to user
	 * 
	 * @returns nothing
	 */
	public void rejectUnregInvitationEntity(Invitation invitation)  {

		
		try {
			invitation.getReceiver().sendNotification(
			invitation.getSender(),"Invitation Rejected!", "Invitation to Join Entity " +
			invitation.getAssignedEntity().getName() +" by "+ "/n" +
			invitation.getReceiver().getfName() + " " +
			invitation.getReceiver().getlName() + " has been rejected!");
		} catch (EmailException e) {
		
			e.printStackTrace();
		}
				
		invitation.setStatus("Rejected");
				
		this.delete();
		invitation.getSender().save();
	}
	
	/**
	 *Handles the invitation response (rejecting or accepting)
	 *
	 * @author     Doaa El-Hawary
	 * @version    2011.0428
	 * @category   C1S15
	 * @param     InvitationId: the invitation that needs a response
	 * @param	   String: the response of the user, "Accept"/"Reject"
	 * @param	   String date: the date of responding to the invitation
	 * @return     void
	 * @throws 	   EmailException
	 */
	public void respondToInvitation(Long invitationId, String response, String date) throws EmailException {
		Invitation invitation = Invitation.findById(invitationId);
		if(response.equals("Accept")) {
			invitation.setStatus("Accepted");
			if(invitation.getAssignedOrganization() != null && invitation.getAssignedRole() != null && invitation.getAssignedEntity() == null) {
				invitation.getReceiver().getOrganizationList().add(invitation.getAssignedOrganization());
				invitation.getReceiver().getRoleList().add(invitation.getAssignedRole());
				invitation.getAssignedOrganization().getMembers().add(invitation.getReceiver());
				String notContent = invitation.getReceiver().getfName() + " " + invitation.getReceiver().getlName() 
					+ "has accepted the invitation to join the organization: " + invitation.getAssignedOrganization().getName();
				invitation.getReceiver().sendNotification(invitation.getSender(), "Invitation Response", notContent);
				invitation.getAssignedOrganization().save();
			}
			if(invitation.getAssignedEntity() != null) {
				invitation.getReceiver().getEntityList().add(invitation.getAssignedEntity());
				invitation.getAssignedEntity().getMembers().add(invitation.getReceiver());
				invitation.getReceiver().getRoleList().add(new Role(invitation.getAssignedEntity(), "Member"));
				String notContent = invitation.getReceiver().getfName() + " " + invitation.getReceiver().getlName() 
					+ "has accepted the invitation to join the entity: " + invitation.getAssignedOrganization().getName();
				invitation.getReceiver().sendNotification(invitation.getSender(), "Invitation Response", notContent);
				invitation.getAssignedEntity().save();
				if(invitation.getAssignedRole() != null) {
					invitation.getReceiver().getRoleList().add(invitation.getAssignedRole());
				}
			}
			
		} else {
			invitation.setStatus("Rejected");
			String notContent = "The invitation sent to " + fName + " " + lName + "has been rejected!";
			invitation.getReceiver().sendNotification(invitation.getSender(), "Invitation Response", notContent);
		}
		//invitation.getReceiver().receivedNotifications().remove(invitation);
		invitation.getSender().save();
		invitation.getReceiver().save();
	}
	
	/**
	 *Allows a user to log in to the system.
	 *
	 * @author     Doaa El-Hawary
	 * @version    2011.0502
	 * @category   C1
	 * @param      Username
	 * @param	   password
	 * @return     User: if the user exists, and entered the correct password,
	 * @return	   "Incorrect password!": in case of incorrect password,
	 * @return	   null: if the user doesn't exist.
	 */
	public static Object connect(String username, String password) {
		List<JPABase> allUsers = User.findAll();
		for(int i=0; i<allUsers.size(); i++) {
			User temp = (User) allUsers.get(i);
			if(temp.getUsername().equals(username)) {
				if(temp.getPassword().equals(password)) {
					return temp;
				}
				else {
					return "Incorrect Password!";
				}
			}
		}
		return null;
	}
	
	
	/**
	 *This method searches for users by their username.
	 *
	 * @author     Doaa El-Hawary
	 * @version    2011.0503
	 * @category   C1
	 * @param      Username
	 * @return     User: the user who has the given username.
	 * @return	   null: if the user doesn't exist.
	 */
	public static User findByUsername(String username2) {
		List<JPABase> allUsers = User.findAll();
		for(int i=0; i<allUsers.size(); i++) {
			User temp = (User) allUsers.get(i);
			if(temp.getUsername().equals(username2)) {
				return temp;
			}
		}
		return null;
	}
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/*public String viewUsersInfo() {
		String info="";
		info += "Name: " + fName + " " + lName;
		info += "\nUsername: " + username;
		info += "\nUser Id: " + this.id;
		return info;
	}*/
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	 /** Overrides toString method, and return the username
	 * 
	 * @author Youssef Selim
	 * @version 2011.0501
	 * @return the username
	 */
	public String toString() {
		return username;
	}
	
	
	/**
	 * deletes a user from the system and checks all ideas, tags, items and plans
	 *  for any contributions by other than this user
	 * if that is the case then a new user is created with the name "Unknown user"
	 * @author Tarek Sheasha
	 * @category C1S3
	 * @version 02.05.2011
	 * @param toBeDeleted
	 * @return nothing
	 */
	public void deleteFromSystem(User toBeDeleted) {
		if(this.isAdmin()) {
			toBeDeleted.setDeleted(true);
			toBeDeleted.save();
		if((toBeDeleted.getItems() == null || toBeDeleted.getItems().isEmpty())
				&& (toBeDeleted.getPlans() == null ||  toBeDeleted.getPlans().isEmpty())
				&& (toBeDeleted.getTagList() == null || toBeDeleted.getTagList().isEmpty())
				&& (toBeDeleted.getIdeaList() == null || toBeDeleted.getIdeaList().isEmpty())) {
		} else {
			User unknown = new User();
			unknown.setfName("Deleted User");
			unknown.setRoleList(toBeDeleted.getRoleList());
			unknown.setlName(" ");
			
			if(toBeDeleted.getIdeaList() != null && !toBeDeleted.getIdeaList().isEmpty())
			
				for(int i = 0; i < toBeDeleted.getIdeaList().size(); i++) {
				   
						toBeDeleted.getIdeaList().get(i).getMembers().remove(toBeDeleted);
					   toBeDeleted.getIdeaList().get(i).getMembers().add(unknown);					 
			}
			
			if(toBeDeleted.getItems() != null && !toBeDeleted.getItems().isEmpty())
				
				for(int i = 0; i < toBeDeleted.getItems().size(); i++) {
				  
					if(toBeDeleted.getItems().get(i).getUsers().size() > 1) {

						toBeDeleted.getItems().get(i).getUsers().remove(toBeDeleted);
					   toBeDeleted.getItems().get(i).getUsers().add(unknown);
					   
				  }
					 
			}
			
			if(toBeDeleted.getPlans() != null && !toBeDeleted.getPlans().isEmpty())
				
				for(int i = 0; i < toBeDeleted.getPlans().size(); i++) {					   
						toBeDeleted.getPlans().get(i).getUsers().remove(toBeDeleted);
					   toBeDeleted.getPlans().get(i).getUsers().add(unknown);
					   					 
			}
			
			if(toBeDeleted.getTagList() != null && !toBeDeleted.getTagList().isEmpty())
				
				for(int i = 0; i < toBeDeleted.getTagList().size(); i++) {
					
				if(toBeDeleted.getTagList().get(i).getOwner() != null && toBeDeleted.getTagList().get(i).getOwner().equals(toBeDeleted))	
					toBeDeleted.getTagList().get(i).setOwner(unknown);
					unknown.getTagList().add(toBeDeleted.getTagList().get(i));
			}
			toBeDeleted = new User();

		}
	}
	}
	
	public String getfName() {
		return fName;
	}

	public void setfName(String fName) {
		this.fName = fName;
	}

	public String getlName() {
		return lName;
	}

	public void setlName(String lName) {
		this.lName = lName;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public boolean isAdmin() {
		return isAdmin;
	}

	public void setAdmin(boolean isAdmin) {
		this.isAdmin = isAdmin;
	}

	public int getPointCounter() {
		return pointCounter;
	}

	public void setPointCounter(int pointCounter) {
		this.pointCounter = pointCounter;
	}

	public List<Idea> getIdeaList() {
		return ideaList;
	}

	public List<Topic> getTopicList() {
		return topicList;
	}


	public List<String> getPrivilegeList() {
		return privilegeList;
	}

	public void setPrivilegeList(List<String> privilegeList) {
		this.privilegeList = (LinkedList<String>) privilegeList;
	}

	public List<Eentity> getEntityList() {
		return entityList;
	}


	public List<Tag> getTagList() {
		return tagList;
	}

	public List<Role> getRoleList() {
		return roleList;
	}

	
	public List<Comment> getCommentList() {
		return commentList;
	}

	public LinkedList<String> getTempPrivilegeList() {
		return (LinkedList<String>) tempPrivilegeList;
	}

	public void setTempPrivilegeList(LinkedList<String> tempPrivilegeList) {
		this.tempPrivilegeList = tempPrivilegeList;
	}

	public List<Organization> getOrganizationList() {
		return  organizationList;
	}

	public List<Notification> getSentNotifications() {
		return sentNotifications;
	}

	public void setSentNotifications(List<Notification> sentNotifications) {
		this.sentNotifications = sentNotifications;
	}

	public List<Notification> getReceivedNotifications() {
		return receivedNotifications;
	}

	public void setReceivedNotifications(List<Notification> receivedNotifications) {
		this.receivedNotifications = receivedNotifications;
	}

	public List<Invitation> getSentInvitations() {
		return sentInvitations;
	}

	public void setSentInvitations(List<Invitation> sentInvitations) {
		this.sentInvitations = sentInvitations;
	}

	public List<Invitation> getReceivedInvitations() {
		return receivedInvitations;
	}

	public void setReceivedInvitations(List<Invitation> receivedInvitations) {
		this.receivedInvitations = receivedInvitations;
	}

	public void setRoleList(List<Role> roleList) {
		this.roleList = roleList;
	}

	public void setIdeaList(List<Idea> ideaList) {
		this.ideaList = ideaList;
	}

	public void setTopicList(List<Topic> topicList) {
		this.topicList = topicList;
	}

	public void setEntityList(List<Eentity> entityList) {
		this.entityList = entityList;
	}

	public void setTagList(List<Tag> tagList) {
		this.tagList = tagList;
	}

	public void setCommentList(List<Comment> commentList) {
		this.commentList = commentList;
	}

	public void setOrganizationList(List<Organization> organizationList) {
		this.organizationList = organizationList;
	}

	public void setTempPrivilegeList(List<String> tempPrivilegeList) {
		this.tempPrivilegeList = (LinkedList<String>) tempPrivilegeList;
	}

	public Request getSentRequest() {
		return sentRequest;
	}

	public void setSentRequest(Request sentRequest) {
		this.sentRequest = sentRequest;
	}

	public Request getReceivedRequest() {
		return receivedRequest;
	}

	public void setReceivedRequest(Request receivedRequest) {
		this.receivedRequest = receivedRequest;
	}

	public void setPlans(List<Plan> plans) {
		this.plans = plans;
	}

	public List<Plan> getPlans() {
		return plans;
	}

	public void setItems(List<Item> items) {
		this.items = items;
	}

	public void setDeleted(boolean isDeleted) {
		this.isDeleted = isDeleted;
	}

	public boolean isDeleted() {
		return isDeleted;
	}

	public List<Item> getItems() {
		return items;
	}


	/**
	 * editOrganizerPermissions() is responsible for editing the permissions of an Organizer inside an entity (can be invoked by Organisation Lead only)
	 * 
	 * @author 		Hossam Saraya
	 * @version 	Apr 29, 2011
	 * @category 	C1S10
	 * 
	 * @params		Entity 	entity: 					The required entity
	 * 				User 	Organizer:					The required Organizer
	 * 				boolean canEdit					
	 * 				boolean canPost
	 * 				boolean canDelete
	 * 				boolean canCreateOrganisation
	 * 				boolean canInvite
	 * 				boolean canAdministerTopic
	 * 				boolean canBeRestricted
	 * 				boolean canAdministerEntity
	 * 
	 * @return		boolean representing operation success or failure
	 */
	public boolean editOrganizerPermissions(Eentity entity,
			boolean canEdit, boolean canPost, boolean canDelete,
			boolean canCreateOrganisation, boolean canInvite,
			boolean canAdministerTopic, boolean canBeRestricted,
			boolean canAdministerEntity) {
		
		for (int i = 0; i < this.getRoleList().size(); i++) {
			Role tmpRole = this.getRoleList().get(i);
			
			// validation
			if(tmpRole.getRelatedEntity().equals(entity) && tmpRole.getUser().equals(this) && tmpRole.getTitle().equals("Organizer")){
				getRoleList().get(i).setCanEdit(canEdit);
				getRoleList().get(i).setCanPost(canPost);
				getRoleList().get(i).setCanDelete(canDelete);
				getRoleList().get(i).setCanCreateOrganisaition(canCreateOrganisation);
				getRoleList().get(i).setCanInvite(canInvite);
				getRoleList().get(i).setCanAdministerTopic(canAdministerTopic);
				getRoleList().get(i).setCanBeRestricted(canBeRestricted);
				getRoleList().get(i).setCanAdministerEntity(canAdministerEntity);
				getRoleList().get(i).save();
				
				return true;
			}
		}
		return false;
	}
	

	public void addComment(Comment comment) {
		if(!has(comment))
			commentList.add(comment);
	}

	public void addTopic(Topic topic) {
		if(!has(topic)){
			topicList.add(topic);
		}
	}

	public void addTag(Tag tag) {
		if(!has(tag)){
			tagList.add(tag);
			tag.addFollowers(this);
		}
	}

	public void addOrganization(Organization organization) {
		if(!has(organization)){
			System.out.println("adding org:"+organization.getName()+"to user "+this.getUsername()+"\'slist");
			organization.save();
			organizationList.add(organization);
			this.save();
			organization.save();
			organization.addMember(this);
		}
	}

	public void addPlan(Plan plan) {
		if(!has(plan)){
			plans.add(plan);
			plan.addUser(this);
		}
	}

	public void addItem(Item item) {
		if (!has(item)) {
			items.add(item);
			item.addUser(this);
		}
		
	}

	public void addIdea(Idea idea) {
		if(!has(idea)) {
			ideaList.add(idea);
			idea.addMember(this);
		}
	}

	public void addEntity(Eentity entity) {
		if(!has(entity)) {
			entityList.add(entity);
		}
	}
	

	private boolean has(Eentity entity) {
		for(int i = 0;i < entityList.size();i++)
			if(entityList.get(i).id == entity.id)
				return true;
		return false;
	}
	
	private boolean has(Idea idea) {
		for(int i = 0;i < ideaList.size();i++)
			if(ideaList.get(i).id == idea.id)
				return true;
		return false;
	}
	
	private boolean has(Plan plan) {
		for(int i = 0;i < plans.size();i++)
			if(plans.get(i).id == plan.id)
				return true;
		return false;
	}
	private boolean has(Comment comment) {
		for(int i = 0;i < commentList.size();i++)
			if(commentList.get(i).id == comment.id)
				return true;
		return false;
	}
	
	private boolean has(Tag tag) {
		for(int i = 0;i < tagList.size();i++)
			if(tagList.get(i).id == tag.id)
				return true;
		return false;
	}
	
	private boolean has(Item item) {
		for(int i = 0;i < items.size();i++)
			if(items.get(i).id == item.id)
				return true;
		return false;
	}
	
	private boolean has(Organization org) {
		for(int i = 0;i < organizationList.size();i++){
			if(organizationList.get(i).id == org.id) {
				System.out.println(org.getName() +" is already in " + this.getUsername() + "\'s org list" );
				return true;
			}
		}
		System.out.println(org.getName() +"is not in " + this.getUsername() + "\'s list");
		return false;
	}
	
	private boolean has(Topic topic) {
		for(int i = 0;i < topicList.size();i++)
			if(topicList.get(i).id == topic.id)
				return true;
		return false;
	}
	

	public void addRole(Role role) {
		roleList.add(role);
	}
}

